package net.facelib.live;

import static net.gdface.utils.ConditionChecks.checkNotNull;

import java.util.concurrent.atomic.AtomicReference;

import net.facelib.sdk.ImageSupport;
import net.gdface.image.BaseLazyImage;
import net.gdface.image.ImageErrorException;
import net.gdface.image.MatType;
import net.gdface.sdk.FRect;

/**
 * 活体检测实现基类<br>
 * @author guyadong
 *
 */
public abstract class BaseFaceLive implements FaceLive{
	protected BaseFaceLive() {
	}

	/**
	 * 返回当前算法支持的矩阵类型:RGB,BGR,RGBA,NV21
	 * @return 矩阵类型
	 */
	protected abstract  MatType getNativeMatType();
	/**
	 * 绑定算法实例到当前线程<br>
	 * 为当前线程申请一个为当前线程专用的算法实例,直到调用{@link #unbindNativeInstanceForCurentThread()}时释放,
	 * 对于非线程安全的算法实例,在类似连续视频检测线程中,需要将算法实例绑定到指定的线程才能获取好的检测效果,
	 * 在这种应用场景下需要重写些方法
	 */
	public void bindNativeInstanceForCurentThread(){
	}
	/**
	 * 解除绑定在当前线程上的算法实例归还到资源池 
	 */
	public void unbindNativeInstanceForCurentThread(){
	}
	/**
	 * 执行活体检测
	 * @param platformImage 当前平台的图像对象,对于android平台，类型为Bitmap,对于通用JDK,类型为BufferedImage 
	 * @param rect 人脸检测方法返回的人脸检测信息原始数据
	 * @param score [out]活体检测得分,可为{@code null}
	 * @return 0--非活体,1--活体,2--缓存标志,3--未知,<0 错误代码 
	 */
	@Override
	public LiveStatus imageLiveProcess(Object platformImage,FRect rect,AtomicReference<Double> score){
		try {
			BaseLazyImage lazyImage = BaseLazyImage.getLazyImageFactory().create(platformImage);
			return matLiveProcess(getNativeMatType(),toNativeMat(lazyImage),lazyImage.getWidth(),lazyImage.getHeight(),rect,score);
		} catch (ImageErrorException e) {
			throw new RuntimeException(e);
		}
	}
	protected byte[] toNativeMat(BaseLazyImage lazyImage){
		try{
			switch(getNativeMatType()){
			case NV21:
				return ImageSupport.toNV21(MatType.BGR, lazyImage.getMatrixBGR(), lazyImage.getWidth(),lazyImage.getHeight());
			case RGB:
				return lazyImage.getMatrixRGB();
			case BGR:
				return lazyImage.getMatrixBGR();
			case RGBA:
				return lazyImage.getMatrixRGBA();
			default:
				throw new IllegalArgumentException("UNSUPPORTED MATTYPE " + getNativeMatType());
			}
		} catch (ImageErrorException e) {
			throw new RuntimeException(e);
		}
	}
	/**
	 * 返回默认实例,为空抛出异常
	 * @return FaceLive instance
	 */
	public static FaceLive getInstance() {		
		return checkNotNull(BaseFaceLiveSupport.INSTANCE,"default instance is null");
	}

	/**
	 * 返回默认实例
	 * @return FaceLive instance
	 */
	public static FaceLive getInstanceUnchecked() {		
		return BaseFaceLiveSupport.INSTANCE;
	}

	/**
	 * 设置默认实例
	 * @param instance
	 */
	public static void setInstance(FaceLive instance) {
		BaseFaceLiveSupport.INSTANCE = instance;
	}

	/**
	 * 返回指定产品ID的实例
	 * @param productID 产品ID
	 * @return FaceLive instance
	 */
	public static FaceLive getInstance(String productID) {		
		return null == productID ? null : BaseFaceLiveSupport.liveInstances.get(productID);
	}

	/**
	 * 设置指定产品ID的实例
	 * @param productID 产品ID
	 * @param instance FaceLive instance
	 */
	public static void setInstance(String productID,FaceLive instance) {
		if(null == productID && null != instance){
			BaseFaceLiveSupport.liveInstances.put(productID,instance);
		}
	}
	
}
